package com.rabbiter.hospital.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rabbiter.hospital.mapper.BedMapper;
import com.rabbiter.hospital.pojo.Bed;
import com.rabbiter.hospital.service.BedService;
import com.rabbiter.hospital.utils.TodayUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

@Service("BedService")
public class BedServiceImpl implements BedService {

    @Resource
    private BedMapper bedMapper;

    /**
     * 查找所有空床位
     * 通过查询条件封装器（QueryWrapper）设置筛选条件，调用床信息映射器（bedMapper）的查询列表功能，
     * 选取状态为0（表示空闲）的床位的ID进行返回，以此实现查找所有当前没有被占用的床位。
     */
    @Override
    public List<Bed> findNullBed() {
        // 初始化查询条件封装器
        QueryWrapper<Bed> wrapper = new QueryWrapper<>();
        // 设置筛选条件：床位状态为0，表示空闲
        wrapper.select("b_id").eq("b_state", 0);
        // 调用映射器的查询列表方法，根据条件获取空闲床位列表
        return this.bedMapper.selectList(wrapper);
    }


    /**
     * 增加床位信息
     */
    @Override
    /**
     * 更新床位信息
     * 只有当床位状态为未使用时，才能更新床位信息
     * @param bed 床位信息对象，包含床位的详细信息
     * @return 如果更新成功，返回true；否则返回false
     */ public Boolean updateBed(Bed bed) {
        // 根据床位ID查询床位信息
        Bed bed1 = this.bedMapper.selectById(bed.getBId());
        // 检查床位是否已被使用，如果已被使用，则不允许更新
        if (bed1.getBState() == 1) return false;
        // 设置床位开始使用日期为当前日期
        bed.setBStart(TodayUtil.getTodayYmd());
        // 设置床位状态为已使用
        bed.setBState(1);
        // 为防止并发冲突，设置版本号
        bed.setVersion(bed1.getVersion());
        // 更新床位信息
        this.bedMapper.updateById(bed);
        return true;
    }

    /**
     * 根据病患ID查询病床信息
     * @param pId 病患ID
     * @return 包含病床信息的列表
     */
    public List<Bed> findBedByPid(int pId) {
        // 创建查询包装器，用于指定查询条件
        QueryWrapper<Bed> wrapper = new QueryWrapper<>();
        // 设置查询条件，病患ID匹配参数pId
        wrapper.eq("p_id", pId);
        // 执行查询并返回结果
        return this.bedMapper.selectList(wrapper);
    }

    /**
     * 分页模糊查询所有检查信息
     * @param pageNumber 分页查询的当前页数
     * @param size       每页的大小
     * @param query      模糊查询的参数
     * @return 包含分页信息和查询结果的HashMap，包含总条数、总页数、当前页和查询到的记录
     */
    @Override
    public HashMap<String, Object> findAllBeds(int pageNumber, int size, String query) {
        // 创建分页对象，指定当前页和每页大小
        Page<Bed> page = new Page<>(pageNumber, size);
        // 创建查询构造器
        QueryWrapper<Bed> wrapper = new QueryWrapper<>();
        // 添加模糊查询条件，针对p_id字段进行模糊匹配
        wrapper.like("p_id", query);
        // 执行分页查询操作，获取分页结果
        IPage<Bed> iPage = this.bedMapper.selectPage(page, wrapper);
        // 创建HashMap用于存储分页查询的结果
        HashMap<String, Object> hashMap = new HashMap<>();
        // 存储总条数
        hashMap.put("total", iPage.getTotal());
        // 存储总页数
        hashMap.put("size", iPage.getPages());
        // 存储当前页
        hashMap.put("pageNumber", iPage.getCurrent());
        // 存储查询到的记录
        hashMap.put("beds", iPage.getRecords());
        // 返回包含分页信息和查询结果的HashMap
        return hashMap;
    }

    /**
     * 根据id查找检查
     * @param bId 床的ID
     * @return 返回找到的床对象，如果找不到则返回null
     */
    @Override
    public Bed findBed(int bId) {
        // 调用映射器的方法根据ID选择床对象
        return this.bedMapper.selectById(bId);
    }

    /**
     * 增加床位信息
     * 此方法首先检查数据库中是否已存在相同的床位ID，如果存在，则不插入数据
     * 如果床位不存在，则设置床位状态为可用（状态码0），并插入数据库
     * @param bed 床位信息对象，包含床位ID和床位状态等信息
     * @return 如果床位成功添加到数据库，则返回true；如果床位ID已存在，则返回false
     */
    @Override
    public Boolean addBed(Bed bed) {
        //检查数据库中是否已存在相同的床位ID
        List<Bed> beds = this.bedMapper.selectList(null);
        for (Bed bed1 : beds) {
            if (bed1.getBId() == bed.getBId()) {
                //如果存在相同ID的床位，则返回false，表示添加失败
                return false;
            }
        }
        //设置床位状态为可用（状态码0）
        bed.setBState(0);
        //插入新的床位信息到数据库
        this.bedMapper.insert(bed);
        //返回true，表示床位添加成功
        return true;
    }

    /**
     * 删除床位信息
     * @param bId 床位ID，用于标识要删除的床位信息
     * @return 返回一个Boolean值，表示删除操作是否成功执行
     */
    @Override
    public Boolean deleteBed(int bId) {
        this.bedMapper.deleteById(bId);
        return true;
    }

    /**
     * 清空床位信息
     * 此方法通过更新数据库中床位记录的各个字段，将床位重置为无人使用状态
     * @param bId 床位ID，标识需要清空信息的床位
     * @return 始终返回true，表示操作成功
     */
    public Boolean emptyBed(int bId) {
        // 创建更新条件封装器，用于指定更新哪些字段以及这些字段的新值
        UpdateWrapper<Bed> wrapper = new UpdateWrapper<>();
        // 设置床位状态字段，-1可能表示未分配或空床，b_reason为空表示没有占用理由，b_start设为null表示没有开始占用时间
        wrapper.set("p_id", -1).set("d_id", -1).set("b_reason", null).set("b_start", null).set("b_state", 0);
        // 指定更新操作仅应用于指定床位ID的记录
        wrapper.eq("b_id", bId);
        // 调用床位数据映射器的更新方法，执行上述更新操作，将床位信息清空
        this.bedMapper.update(null, wrapper);
        // 返回true，表示床位信息成功被清空
        return true;
    }

    /**
     * 统计今天挂号人数
     * @param bStart 今天开始时间，用于查询条件，格式为'YYYY-MM-DD HH:MM:SS'
     * @return 今天的挂号人数
     */
    @Override
    public int bedPeople(String bStart) {
        return this.bedMapper.bedPeople(bStart);
    }


}
